package com.vkmessenger.net.clients;

import com.google.gson.Gson;
import com.vkmessenger.net.handlers.LongPollResponseHandler;
import com.vkmessenger.net.json.LongPollResponse;
import com.vkmessenger.net.json.LongPollServerConfig;
import org.apache.http.client.HttpClient;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.BasicResponseHandler;

import java.io.IOException;
import java.util.concurrent.*;
import java.util.logging.Logger;

/**
 * Created by IntelliJ IDEA.
 * User: Evgeniy Krasko
 * Date: 30.05.12
 * Time: 13:38
 */
public class LongPollClient extends Thread {
    private static Logger logger = Logger.getLogger(LongPollClient.class.getName());
    private static final int SLEEP_ON_LONG_POLL_FAILURE = 10000;

    private HttpClient client = HttpClientFactory.getTunedHttpClient();
    private ResponseHandler<String> responseHandler = new BasicResponseHandler();
    private LongPollResponseHandler handlerToSubmit = LongPollResponseHandler.INSTANCE;
    private Gson gson = new Gson();

    private volatile boolean stop = false;


    public void run() {
        LongPollServerConfig config = null;
        Future<LongPollServerConfig> configFuture = null;
        while (!stop) {
            if (configFuture == null) {
                configFuture = WebClient.INSTANCE.getLongPollConfig();
                try {
                    config = configFuture.get(SLEEP_ON_LONG_POLL_FAILURE, TimeUnit.MILLISECONDS);
                    logger.info("Got long poll connection data, server:" + config.response.server);
                } catch (Exception e) {
                    logger.warning("Can't get config for long poll");
                    config = null;
                }
            }
            if (config != null) {
                HttpGet request = new HttpGet("http://"
                        + config.response.server +
                        "?act=a_check" +
                        "&key=" + config.response.key +
                        "&ts=" + config.response.ts +
                        "&wait=25&mode=2");
                try {
                    String json = client.execute(request, responseHandler);
                    logger.info("Long poll response:" + json);
                    LongPollResponse response = gson.fromJson(json, LongPollResponse.class);
                    if(response == null || response.updates == null) {
                        configFuture = null;
                        logger.info("Long poll connection down, trying to acquire a new one.");
                    }else{
                        config.response.ts = response.ts;
                        handlerToSubmit.handleResponse(response);
                    }
                } catch (IOException e) {
                    logger.info("Long poll connection down, trying to acquire a new one.");
                    configFuture = null;
                }
            } else {
                try {
                    Thread.sleep(SLEEP_ON_LONG_POLL_FAILURE);
                } catch (InterruptedException e1) {
                    stop = true;
                }
            }
        }
        logger.info("Long poll client shutting down...");
    }

    public void stopListening() {
        stop = true;
    }
}
